/* -*-jde-*- */
package app.alumnoe.cv;

import app.alumnoe.cv.beans.Formacion;
import app.alumnoe.cv.beans.TecnicoProfesional;
import app.alumnoe.cv.beans.TipoContratacion;
import app.alumnoe.cv.beans.ExperienciaProfesional;
import app.alumnoe.cv.beans.Idioma;
import app.alumnoe.cv.beans.Investigacion;
import app.util.Fecha;
import java.util.LinkedList;
import app.conexion.Conexion;
import app.conexion.ConexionException;
import app.util.SQLInjectionException;
import app.util.Validator;
import app.util.appException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Bean CV Todo el Curriculum Vitae para el alumno / egresado
 *
 * @author Victor Miguel Peralta Santa Anna
 * @since Enero 2012
 * @version 0.1
 */
public class CV {

    /**
     * El identificador del usuario
     */
    private int nIdUsuario;
    /**
     * El identificador de CV
     */
    private int nIdCV;
    /**
     * La fecha de última modificación del CV del usuario.
     */
    private Fecha dFechaActualizacion;
    /**
     * Objetivo para el CV
     */
    private String sObjetivo;
    /**
     * Fecha en la que terminó la carrera
     */
    private Fecha dFechaFinalCarrera;
    /**
     * Porcentaje de créditos de la carrera
     */
    private String sCreditos;
    /**
     * Areas de interes / especialidad
     */
    private String sAreasInteres;
    /**
     * Esta dispuesto a viajar para un nuevo empleo
     */
    private boolean bDispuestoAViajar;
    /**
     * Esta dispuesto a reubicarse para el nuevo empleo
     */
    private boolean bDispuestoAReubicarse;
    /**
     * La lista de conocimientos tecnico profesionales de este CV
     */
    private LinkedList<TecnicoProfesional> tecnicosProfesionales;
    /**
     * La lista de formaciones academicas y pofesionales de este CV
     */
    private LinkedList<Formacion> formaciones;
    /**
     * La lista de experiencias profesionales para este CV
     */
    private LinkedList<ExperienciaProfesional> experienciasProfesionales;
    /**
     * La lista de articulos de investigación para este CV
     */
    private LinkedList<Investigacion> articulosInvestigacion;
    /**
     * La lista de tipo de contratacion para este CV
     */
    private LinkedList<TipoContratacion> tipoContrataciones;
    /**
     * LA lista de idiomas para este CV
     */
    private LinkedList<Idioma> idiomas;

    /**
     * Carga un curriculum vitae para
     *
     * @param nIdCV
     * @param nIdUsuario
     */
    public CV(int nIdCV, int nIdUsuario) throws appException {

        this.nIdCV = nIdCV;
        this.nIdUsuario = nIdUsuario;

        try {

            Conexion con = new Conexion();
            String query = "select * from cv where nidcv = " + nIdCV + ";";

            if (!Validator.checkSQLInjection(query)) {
                ResultSet r = con.exec(query);

                while (r.next()) {

                    Fecha f1 = new Fecha(r.getString("dfechaactualizacion"));
                    String s1 = r.getString("sobjetivo");
                    String fechaFin = r.getString("dfechafinalcarrera");
                    Fecha f2 = (fechaFin == null) ? null : new Fecha(fechaFin);
                    String s2 = r.getString("screditos");
                    String s3 = r.getString("sareasinteres");
                    boolean b1 = r.getBoolean("bdispuestoaviajar");
                    boolean b2 = r.getBoolean("bdispuestoareubicarse");

                    this.dFechaActualizacion = f1;
                    this.sObjetivo = s1;
                    this.dFechaFinalCarrera = f2;
                    this.sCreditos = s2;
                    this.sAreasInteres = s3;
                    this.bDispuestoAViajar = b1;
                    this.bDispuestoAReubicarse = b2;
                }

                loadListsCV();
                con.close();
            }

        } catch (SQLException ex) {
            System.err.println(ex);
            Logger.getLogger(CV.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pudo recuperar el elemento: CV");
        } catch (ConexionException ce) {
            System.err.println(ce);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ce);
            throw new appException("No se pudo recuperar el elemento: CV");
        } catch (SQLInjectionException sqlie) {
            System.err.println(sqlie);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, sqlie);
            throw new appException(sqlie.getMessage());
        }

    }

    /**
     * Carga todas las listas para que el CV tenga en ese momento la información
     * más actualizada Servirá para el despligue de la página que se llevará a
     * cabo después.
     */
    public void loadListsCV() throws appException {
        if (nIdCV != -1) {
            TecnicosProfesionales tc = new TecnicosProfesionales(nIdCV);
            Formaciones f = new Formaciones(nIdCV);
            ExperienciasProfesionales ep = new ExperienciasProfesionales(nIdCV);
            Investigaciones inv = new Investigaciones(nIdCV);
            TipoContrataciones tcon = new TipoContrataciones(nIdCV);
            Idiomas id = new Idiomas(nIdCV);

            tecnicosProfesionales = tc.getTecnicosProfesionales();
            formaciones = f.getFormaciones();
            experienciasProfesionales = ep.getExperienciasprofesionales();
            articulosInvestigacion = inv.getInvestigaciones();
            tipoContrataciones = tcon.getTipocontrataciones();
            idiomas = id.getIdiomas();

        }
    }

    /**
     * El constructor para el CV base, los agregados se quedan en otros métodos.
     *
     * @param nIdUsuario El identificador para el usuario
     * @param nIdCV El identifiacor para el CV
     * @param dFechaActualizacion La fecha de actualización para el CV
     * @param sObjetivo El objetivo que se considere en el cv
     * @param dFechaFinalCarrera La fecha de final de la carrera
     * @param sCreditos Los creditos de avance que se tiene de la carrera
     * @param sAreasInteres Las areas de interes que se poseen
     * @param bDispuestoAViajar Si se está dispuesto o no a viajar
     * @param bDispuestoAReubicarse Si se esta o no dispuesto a reubicarse
     */
    public CV(int nIdUsuario, int nIdCV, Fecha dFechaActualizacion, String sObjetivo,
            Fecha dFechaFinalCarrera, String sCreditos, String sAreasInteres,
            boolean bDispuestoAViajar, boolean bDispuestoAReubicarse) {
        this.nIdUsuario = nIdUsuario;
        this.nIdCV = nIdCV;
        this.dFechaActualizacion = dFechaActualizacion;
        this.sObjetivo = sObjetivo;
        this.dFechaFinalCarrera = dFechaFinalCarrera;
        this.sCreditos = sCreditos;
        this.sAreasInteres = sAreasInteres;
        this.bDispuestoAViajar = bDispuestoAViajar;
        this.bDispuestoAReubicarse = bDispuestoAReubicarse;
    }

    @Override
    public String toString() {
        return "CV{" + "nIdUsuario=" + getnIdUsuario() + ", nIdCV=" + getnIdCV()
                + ", dFechaActualizacion=" + getdFechaActualizacion() + ", sObjetivo="
                + getsObjetivo() + ", dFechaFinalCarrera=" + getdFechaFinalCarrera() + ", sCreditos="
                + getsCreditos() + ", sAreasInteres=" + getsAreasInteres() + ", bDispuestoAViajar="
                + isbDispuestoAViajar() + ", bDispuestoAReubicarse=" + isbDispuestoAReubicarse()
                + ", conocimientosTecProf=" + getConocimientosTecProf() + ", formaciones="
                + getFormaciones() + ", experiencia=" + getExperiencia() + ", articulos=" + getArticulos()
                + ", contratacion=" + getContratacion() + ", idiomas=" + getIdiomas() + '}';
    }

    /**
     * Guarda el objeto en la base de datos independientemente si éste es nuevo
     * o no.
     */
    public void save() throws appException {

        try {

            Conexion con = new Conexion();
            String query = "select ";
            String fechaFin = getdFechaFinalCarrera() != null ? ("'" + getdFechaFinalCarrera().toString() + "'") : "null";

            if (getnIdCV() == -1) {
                query += "addCV(" + getnIdUsuario();
                query += ", '" + Fecha.getTodayDate().toString() + "'";
                query += ", '" + getsObjetivo() + "'";
                query += ", " + fechaFin + "";
                query += ", '" + getsCreditos() + "'";
                query += ", '" + getsAreasInteres() + "'";
                query += ", '" + isbDispuestoAViajar() + "'";
                query += ", " + isbDispuestoAReubicarse() + "";
                query += ");";

                if (!Validator.checkSQLInjection(query)) {
                    ResultSet r = con.exec(query);
                    while (r.next()) {
                        int resultado = r.getInt("addCV");
                        this.nIdCV = resultado;
                    }
                }

            } else {

                query += "updateCV(" + getnIdCV();
                query += ", '" + Fecha.getTodayDate().toString() + "'";
                query += ", '" + getsObjetivo() + "'";
                query += ", " + fechaFin + "";
                query += ", '" + getsCreditos() + "'";
                query += ", '" + getsAreasInteres() + "'";
                query += ", '" + isbDispuestoAViajar() + "'";
                query += ", " + isbDispuestoAReubicarse() + "";
                query += ");";

                if (!Validator.checkSQLInjection(query)) {
                    con.exec(query);
                }
            }
            con.close();

        } catch (SQLException ex) {
            System.err.println(ex);
            Logger.getLogger(Formacion.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pudo guardar el elemento: CV");
        } catch (ConexionException ce) {
            System.err.println(ce);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ce);
            throw new appException("No se pudo guardar el elemento: CV");
        } catch (SQLInjectionException sqlie) {
            System.err.println(sqlie);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, sqlie);
            throw new appException(sqlie.getMessage());
        }

    }

    /**
     * Borra el objeto de la base de datos.
     */
    public void delete() throws appException {
        try {
            Conexion con = new Conexion();
            String query = "select deleteCV( " + getnIdUsuario() + "," + getnIdCV() + " );";
            con.exec(query);
            con.close();
        } catch (ConexionException ce) {
            System.err.println(ce);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ce);
            throw new appException("No se pudo borrar el elemento: CV");
        }
    }

    /**
     * Guarda absolutamente todos los componentes que conforman a este CV con
     * una sola llamada a este metodo.
     *
     * @throws appException
     */
    public void saveAll() throws appException {

        this.save();

        for (TecnicoProfesional tp : tecnicosProfesionales) {
            tp.save();
        }

        for (Formacion f : formaciones) {
            f.save();
        }

        for (ExperienciaProfesional ep : experienciasProfesionales) {
            ep.save();
        }

        for (Investigacion i : articulosInvestigacion) {
            i.save();
        }

        for (TipoContratacion tc : tipoContrataciones) {
            tc.save();
        }

        for (Idioma i : idiomas) {
            i.save();
        }
    }

    /**
     * Borra todos los componentes de un CV en una sola llamada a función
     */
    public void deleteAll() throws appException {

        for (TecnicoProfesional tp : tecnicosProfesionales) {
            tp.delete();
        }

        for (Formacion f : formaciones) {
            f.delete();
        }

        for (ExperienciaProfesional ep : experienciasProfesionales) {
            ep.delete();
        }

        for (Investigacion i : articulosInvestigacion) {
            i.delete();
        }

        for (TipoContratacion tc : tipoContrataciones) {
            tc.delete();
        }

        for (Idioma i : idiomas) {
            i.delete();
        }

        this.delete();
    }

    /**
     * Conexiones de prueba a la base de datos
     *
     * @param args
     * @throws ConexionException
     * @throws SQLException
     * @throws appException
     */
    public static void main(String args[]) throws ConexionException, SQLException, appException {

        //nuevo
        CV f = new CV(2, -1, new Fecha(1009, 02, 18), "objetivo", null, "creditos", "areas interes", true, true);
        f.save();

        CV f1 = new CV(1, 2);

        f1.save();
        //f.delete();

        System.out.println(f1);
    }

    /**
     * @return the nIdUsuario
     */
    public int getnIdUsuario() {
        return nIdUsuario;
    }

    /**
     * @return the nIdCV
     */
    public int getnIdCV() {
        return nIdCV;
    }

    /**
     * @return the dFechaActualizacion
     */
    public Fecha getdFechaActualizacion() {
        return dFechaActualizacion;
    }

    /**
     * @param dFechaActualizacion the dFechaActualizacion to set
     */
    public void setdFechaActualizacion(Fecha dFechaActualizacion) {
        this.dFechaActualizacion = dFechaActualizacion;
    }

    /**
     * @return the sObjetivo
     */
    public String getsObjetivo() {
        return sObjetivo;
    }

    /**
     * @param sObjetivo the sObjetivo to set
     */
    public void setsObjetivo(String sObjetivo) {
        this.sObjetivo = sObjetivo;
    }

    /**
     * @return the dFechaFinalCarrera
     */
    public Fecha getdFechaFinalCarrera() {
        return dFechaFinalCarrera;
    }

    /**
     * @param dFechaFinalCarrera the dFechaFinalCarrera to set
     */
    public void setdFechaFinalCarrera(Fecha dFechaFinalCarrera) {
        this.dFechaFinalCarrera = dFechaFinalCarrera;
    }

    /**
     * @return the sCreditos
     */
    public String getsCreditos() {
        return sCreditos;
    }

    /**
     * @param sCreditos the sCreditos to set
     */
    public void setsCreditos(String sCreditos) {
        this.sCreditos = sCreditos;
    }

    /**
     * @return the sAreasInteres
     */
    public String getsAreasInteres() {
        return sAreasInteres;
    }

    /**
     * @param sAreasInteres the sAreasInteres to set
     */
    public void setsAreasInteres(String sAreasInteres) {
        this.sAreasInteres = sAreasInteres;
    }

    /**
     * @return the bDispuestoAViajar
     */
    public boolean isbDispuestoAViajar() {
        return bDispuestoAViajar;
    }

    /**
     * @param bDispuestoAViajar the bDispuestoAViajar to set
     */
    public void setbDispuestoAViajar(boolean bDispuestoAViajar) {
        this.bDispuestoAViajar = bDispuestoAViajar;
    }

    /**
     * @return the bDispuestoAReubicarse
     */
    public boolean isbDispuestoAReubicarse() {
        return bDispuestoAReubicarse;
    }

    /**
     * @param bDispuestoAReubicarse the bDispuestoAReubicarse to set
     */
    public void setbDispuestoAReubicarse(boolean bDispuestoAReubicarse) {
        this.bDispuestoAReubicarse = bDispuestoAReubicarse;
    }

    /**
     * @return the conocimientosTecProf
     */
    public LinkedList<TecnicoProfesional> getConocimientosTecProf() {
        return tecnicosProfesionales;
    }

    /**
     * @param conocimientosTecProf the conocimientosTecProf to set
     */
    public void setConocimientosTecProf(LinkedList<TecnicoProfesional> conocimientosTecProf) {
        this.tecnicosProfesionales = conocimientosTecProf;
    }

    /**
     * @return the formaciones
     */
    public LinkedList<Formacion> getFormaciones() {
        return formaciones;
    }

    /**
     * @param formaciones the formaciones to set
     */
    public void setFormaciones(LinkedList<Formacion> formaciones) {
        this.formaciones = formaciones;
    }

    /**
     * @return the experiencia
     */
    public LinkedList<ExperienciaProfesional> getExperiencia() {
        return experienciasProfesionales;
    }

    /**
     * @param experiencia the experiencia to set
     */
    public void setExperiencia(LinkedList<ExperienciaProfesional> experiencia) {
        this.experienciasProfesionales = experiencia;
    }

    /**
     * @return the articulos
     */
    public LinkedList<Investigacion> getArticulos() {
        return articulosInvestigacion;
    }

    /**
     * @param articulos the articulos to set
     */
    public void setArticulos(LinkedList<Investigacion> articulos) {
        this.articulosInvestigacion = articulos;
    }

    /**
     * @return the contratacion
     */
    public LinkedList<TipoContratacion> getContratacion() {
        return tipoContrataciones;
    }

    /**
     * @param contratacion the contratacion to set
     */
    public void setContratacion(LinkedList<TipoContratacion> contratacion) {
        this.tipoContrataciones = contratacion;
    }

    /**
     * @return the idiomas
     */
    public LinkedList<Idioma> getIdiomas() {
        return idiomas;
    }

    /**
     * @param idiomas the idiomas to set
     */
    public void setIdiomas(LinkedList<Idioma> idiomas) {
        this.idiomas = idiomas;
    }
}
